package cn.maihe.elg.operation.model.bo;

import cn.hutool.crypto.digest.MD5;
import cn.maihe.elg.operation.model.enums.CenterNoEnum;
import cn.maihe.elg.operation.utils.CreateGuaranteeUtil;
import cn.maihe.elg.operation.utils.ElgLogger;
import cn.maihe.elg.operation.utils.StringUtil;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;

/**
 * @Description ofd结构化xml
 * @Author WJH
 * @Date 2021/09/28
 */
@Getter
@Setter
@Builder
@Slf4j
public class OfdStructXmlBO implements Serializable {

    /**
     * ORDER_ID为公共资源交易电子保函的订单号，为本公共资源交易电子保函文件格式标准文件的唯一标识。
     */
    private String centerOrderId;
    private String guaranteeNo;

    private TenderInfo tenderInfo;
    private Guarantor guarantor;
    private Bidder bidder;
    private GuaranteeInfo guaranteeInfo;
    private BeneficiaryInfo beneficiaryInfo;
    private GuaranteeAttachment guaranteeAttachment;
    private InvoiceInfo invoiceInfo;

    @Override
    public String toString() {
        StringBuilder ofdXml = new StringBuilder();
        ofdXml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        String DZBHINFOText = genDZBHINFO_text();
        String DZBHINFOTextMD5 = genDZBHMD5(DZBHINFOText);
        ElgLogger.info(log, l -> l.info("traceId={} => 中心订单号[{}][{}]服务 DZBHINFOText:{} DZBHINFOTextMD5:{}", centerOrderId, centerOrderId, "genDZBHINFO_text", DZBHINFOText, DZBHINFOTextMD5));
        ofdXml.append("<DZBH>")
                .append("<DZBHMD5>" + DZBHINFOTextMD5 + "</DZBHMD5>")
                .append("<DZBHINFO>" + DZBHINFOText + "</DZBHINFO>")
                .append("</DZBH>");
        return ofdXml.toString();
    }

    /**
     * DZBHMD5为对DZBHINFO整个节点的字符串进行去除空格，
     * 转大写后的获取的MD5哈希值，用于验证DZBHINFO节点完整性
     *
     * @param dzbhinfoText
     * @return
     */
    public String genDZBHMD5(String dzbhinfoText) {
        return MD5.create().digestHex(StringUtil.removeAllWhitespaceFast(dzbhinfoText).toUpperCase()).toUpperCase();
    }

    /**
     * DZBHINFO 节点内容
     *
     * @return
     */
    public String genDZBHINFO_text() {
        StringBuilder info = new StringBuilder();
        info.append("<ORDER_ID>" + centerOrderId.trim() + "</ORDER_ID>");
        info.append("<GUARANTEE_NO>" + guaranteeNo.trim() + "</GUARANTEE_NO>");
        info
                .append(guaranteeInfo)
                .append(beneficiaryInfo)
                .append(bidder)
                .append(tenderInfo)
                .append(guarantor)
                .append(invoiceInfo)
                .append(guaranteeAttachment);
        return info.toString().replace("&", "&amp;");
    }

    /**
     * 招标项目和标段信息（TENDER_INFO）
     */
    @Getter
    @Setter
    @Builder
    public static class TenderInfo implements Serializable {
        private CenterNoEnum centerNoEnum;

        private String APPROVAL_CODE;
        private String INVEST_PROJECT_CODE;
        private String TENDER_PROJECT_CODE;
        private String TENDER_PROJECT_NAME;
        private String SECTION_CODE;
        private String SECTION_NAME;

        private String CONTRACT_RECKON_PRICE;
        private String TENDERER;
        private String TENDERER_CREDIT_CODE;
        private String TENDERER_BANK_CODE;

        private String TENDERER_BANK_OPENBANK;
        private String TENDERER_BANK_ACCOUNT;
        private String TENDERER_CONTACT;
        private String TENDERER_CONTACT_TEL;
        private String TENDERER_CONTACT_ADDRESS;
        private String PROJECT_DAYS;
        private String PROJECT_ADDRESS;
        private String INVITE_TYPE;

        private String CITY_CODE;
        private String TENDER_PROJECT_TYPE;
        private String BID_OPEN_TIME;
        private String VALID_PERIOD;
        private String BID_BOND;

        private String TENDER_NOTICE_URL;
        private String TENDER_FILE_URL;
        private String TENDER_FILE_MD5;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
             sb.append("<TENDER_INFO")
                    .append(" APPROVAL_CODE=" + trim(APPROVAL_CODE))
                    .append(" INVEST_PROJECT_CODE=" + trim(INVEST_PROJECT_CODE))
                    .append(" TENDER_PROJECT_CODE=" + trim(TENDER_PROJECT_CODE))
                    .append(" TENDER_PROJECT_NAME=" + trim(TENDER_PROJECT_NAME))
                    .append(" SECTION_CODE=" + trim(SECTION_CODE))
                    .append(" SECTION_NAME=" + trim(SECTION_NAME))

                    .append(" CONTRACT_RECKON_PRICE=" + trim(CONTRACT_RECKON_PRICE))
                    .append(" TENDERER=" + trim(TENDERER))
                    .append(" TENDERER_CREDIT_CODE=" + trim(TENDERER_CREDIT_CODE))
                    .append(" TENDERER_BANK_CODE=" + trim(TENDERER_BANK_CODE))
                    .append(" TENDERER_BANK_OPENBANK=" + trim(TENDERER_BANK_OPENBANK))
                    .append(" TENDERER_BANK_ACCOUNT=" + trim(TENDERER_BANK_ACCOUNT))

                    .append(" TENDERER_CONTACT=" + trim(TENDERER_CONTACT))
                    .append(" TENDERER_CONTACT_TEL=" + trim(TENDERER_CONTACT_TEL));

                    // 厦门新增的xml字段 福建省内其他地区不需要
                    if(CreateGuaranteeUtil.isXiaMen(centerNoEnum)){
                        sb.append(" TENDERER_CONTACT_ADDRESS=" + trim(TENDERER_CONTACT_ADDRESS))
                        .append(" PROJECT_DAYS=" + trim(PROJECT_DAYS))
                        .append(" PROJECT_ADDRESS=" + trim(PROJECT_ADDRESS))
                        .append(" INVITE_TYPE=" + trim(INVITE_TYPE));
                    }
                    // 厦门新增的xml字段 福建省内其他地区不需要

                    sb.append(" CITY_CODE=" + trim(CITY_CODE))
                    .append(" TENDER_PROJECT_TYPE=" + trim(TENDER_PROJECT_TYPE))
                    .append(" BID_OPEN_TIME=" + trim(BID_OPEN_TIME))
                    .append(" VALID_PERIOD=" + trim(VALID_PERIOD))

                    .append(" BID_BOND=" + trim(BID_BOND))
                    .append(" TENDER_NOTICE_URL=" + trim(TENDER_NOTICE_URL))
                    .append(" TENDER_FILE_URL=" + trim(TENDER_FILE_URL))
                    .append(" TENDER_FILE_MD5=" + trim(TENDER_FILE_MD5))
                    .append("></TENDER_INFO>");
            return sb.toString();
        }

    }

    /**
     * 工程担保保证人信息(GUARANTOR)
     */
    @Setter
    @Getter
    @Builder
    public static class Guarantor implements Serializable {
        private String GUARANTOR_NAME;
        private String GUARANTOR_CREDIT_CODE;
        private String GUARANTOR_LEGAL_PERSON;
        private String GUARANTOR_LEGAL_IDCARD_TYPE;
        private String GUARANTOR_LEGAL_IDCARD;

        private String BANK_CODE;
        private String GUARANTOR_ADDRESS;
        private String GUARANTOR_EMAIL;
        private String GUARANTOR_POSTCODE;
        private String GUARANTOR_PHONE;

        private String GUARANTOR_TAX;
        private String GUARANTOR_BUSSINESS_NAME;
        private String GUARANTOR_BUSSINESS_TEL;
        private String GUARANTOR_TECHNOLOGY_NAME;
        private String GUARANTOR_TECHNOLOGY_TEL;


        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            return sb.append("<GUARANTOR")
                    .append(" GUARANTOR_NAME=" + trim(GUARANTOR_NAME))
                    .append(" GUARANTOR_CREDIT_CODE=" + trim(GUARANTOR_CREDIT_CODE))
                    .append(" GUARANTOR_LEGAL_PERSON=" + trim(GUARANTOR_LEGAL_PERSON))
                    .append(" GUARANTOR_LEGAL_IDCARD_TYPE=" + trim(GUARANTOR_LEGAL_IDCARD_TYPE))
                    .append(" GUARANTOR_LEGAL_IDCARD=" + trim(GUARANTOR_LEGAL_IDCARD))

                    .append(" BANK_CODE=" + trim(BANK_CODE))
                    .append(" GUARANTOR_ADDRESS=" + trim(GUARANTOR_ADDRESS))
                    .append(" GUARANTOR_EMAIL=" + trim(GUARANTOR_EMAIL))
                    .append(" GUARANTOR_POSTCODE=" + trim(GUARANTOR_POSTCODE))
                    .append(" GUARANTOR_PHONE=" + trim(GUARANTOR_PHONE))

                    .append(" GUARANTOR_TAX=" + trim(GUARANTOR_TAX))
                    .append(" GUARANTOR_BUSSINESS_NAME=" + trim(GUARANTOR_BUSSINESS_NAME))
                    .append(" GUARANTOR_BUSSINESS_TEL=" + trim(GUARANTOR_BUSSINESS_TEL))
                    .append(" GUARANTOR_TECHNOLOGY_NAME=" + trim(GUARANTOR_TECHNOLOGY_NAME))
                    .append(" GUARANTOR_TECHNOLOGY_TEL=" + trim(GUARANTOR_TECHNOLOGY_TEL))
                    .append("></GUARANTOR>")
                    .toString();


        }


    }

    /**
     * 投保人信息(BIDDER)
     */
    @Getter
    @Setter
    @Builder
    public static class Bidder implements Serializable {
        private String BIDDER_NAME;
        private String BIDDER_CREDIT_CODE;
        private String BIDDER_CONTACT_NAME;
        private String BIDDER_CONTACT_TEL;
        private String BIDDER_CONTACT_IDCARD;
        private String BIDDER_CONTACT_IDCARD_TYPE;
        private String BIDDER_ADDRESS;
        private String BIDDER_EAMIL;
        private String LEGAL_PERSON_NAME;
        private String LEGAL_PERSON_IDCARD;
        private String LEGAL_PERSON_IDCARD_TYPE;
        private String LEGAL_PERSON_TEL;

        @Override
        public String toString() {
            return new StringBuilder("<BIDDER")
                    .append(" BIDDER_NAME=" + trim(BIDDER_NAME))
                    .append(" BIDDER_CREDIT_CODE=" + trim(BIDDER_CREDIT_CODE))
                    .append(" BIDDER_CONTACT_NAME=" + trim(BIDDER_CONTACT_NAME))
                    .append(" BIDDER_CONTACT_TEL=" + trim(BIDDER_CONTACT_TEL))
                    .append(" BIDDER_CONTACT_IDCARD=" + trim(BIDDER_CONTACT_IDCARD))
                    .append(" BIDDER_CONTACT_IDCARD_TYPE=" + trim(BIDDER_CONTACT_IDCARD_TYPE))
                    .append(" BIDDER_ADDRESS=" + trim(BIDDER_ADDRESS))
                    .append(" BIDDER_EAMIL=" + trim(BIDDER_EAMIL))
                    .append(" LEGAL_PERSON_NAME=" + trim(LEGAL_PERSON_NAME))
                    .append(" LEGAL_PERSON_IDCARD=" + trim(LEGAL_PERSON_IDCARD))
                    .append(" LEGAL_PERSON_IDCARD_TYPE=" + trim(LEGAL_PERSON_IDCARD_TYPE))
                    .append(" LEGAL_PERSON_TEL=" + trim(LEGAL_PERSON_TEL))
                    .append("></BIDDER>").toString();


        }
    }

    /**
     * 保函基本信息（GUARANTEE_INFO）
     */
    @Getter
    @Setter
    @Builder
    public static class GuaranteeInfo implements Serializable {
        private String GUARANTEE_NO;
        private String CREATE_TIME;
        private String SERVICE_BEGIN_TIME;
        private String SERVICE_END_TIME;
        private String BID_BOND;
        private String AMOUNT;
        private String RATE;
        private String PAY_TYPE;

        private String PAY_ACCOUNT;
        private String PAY_NAME;
        private String PAY_PHONE;
        private String PAY_BANK_OPENBANK;
        private String GUARANTEE_DUTY;
        private String GUARANTEE_PROPERTY;

        private String CLAIM_CLAUSE;
        private String PAY_LIMITATION;
        private String BANK_RECORD_NO;
        private String APPLICABLE_LAW;
        private String REMARK;


        @Override
        public String toString() {
            return new StringBuilder("<GUARANTEE_INFO")
                    .append(" GUARANTEE_NO=" + trim(GUARANTEE_NO))
                    .append(" CREATE_TIME=" + trim(CREATE_TIME))
                    .append(" SERVICE_BEGIN_TIME=" + trim(SERVICE_BEGIN_TIME))
                    .append(" SERVICE_END_TIME=" + trim(SERVICE_END_TIME))
                    .append(" BID_BOND=" + trim(BID_BOND))
                    .append(" AMOUNT=" + trim(AMOUNT))
                    .append(" RATE=" + trim(RATE))
                    .append(" PAY_TYPE=" + trim(PAY_TYPE))

                    .append(" PAY_ACCOUNT=" + trim(PAY_ACCOUNT))
                    .append(" PAY_NAME=" + trim(PAY_NAME))
                    .append(" PAY_PHONE=" + trim(PAY_PHONE))
                    .append(" PAY_BANK_OPENBANK=" + trim(PAY_BANK_OPENBANK))
                    .append(" GUARANTEE_DUTY=" + trim(GUARANTEE_DUTY))
                    .append(" GUARANTEE_PROPERTY=" + trim(GUARANTEE_PROPERTY))

                    .append(" CLAIM_CLAUSE=" + trim(CLAIM_CLAUSE))
                    .append(" PAY_LIMITATION=" + trim(PAY_LIMITATION))
                    .append(" BANK_RECORD_NO=" + trim(BANK_RECORD_NO))
                    .append(" APPLICABLE_LAW=" + trim(APPLICABLE_LAW))
                    .append(" REMARK=" + trim(REMARK))
                    .append("></GUARANTEE_INFO>").toString();

        }
    }

    /**
     * 受益人信息(BENEFICIARY_INFO)
     */
    @Getter
    @Setter
    @Builder
    public static class BeneficiaryInfo implements Serializable {
        private String BENEFICIARY;
        private String BENEFICIARY_CREDIT_CODE;
        private String BENEFICIARY_BANK_ACCOUNT;
        private String BENEFICIARY_BANK_CODE;
        private String BENEFICIARY_BANK_OPENBANK;
        private String BENEFICIARY_CONTACT;
        private String BENEFICIARY_CONTACT_TEL;

        @Override
        public String toString() {
            return new StringBuilder("<BENEFICIARY_INFO")
                    .append(" BENEFICIARY=" + trim(BENEFICIARY))
                    .append(" BENEFICIARY_CREDIT_CODE=" + trim(BENEFICIARY_CREDIT_CODE))
                    .append(" BENEFICIARY_BANK_ACCOUNT=" + trim(BENEFICIARY_BANK_ACCOUNT))
                    .append(" BENEFICIARY_BANK_CODE=" + trim(BENEFICIARY_BANK_CODE))
                    .append(" BENEFICIARY_BANK_OPENBANK=" + trim(BENEFICIARY_BANK_OPENBANK))
                    .append(" BENEFICIARY_CONTACT=" + trim(BENEFICIARY_CONTACT))
                    .append(" BENEFICIARY_CONTACT_TEL=" + trim(BENEFICIARY_CONTACT_TEL))
                    .append("></BENEFICIARY_INFO>").toString();
        }
    }

    /**
     * 附件信息(GUARANTEE_ATTACHMENT)
     */
    @Getter
    @Setter
    @Builder
    public static class GuaranteeAttachment implements Serializable {
        private CenterNoEnum centerNoEnum;
        private String WARRANTY_FILE_NAME;
        private String WARRANTY_MD5;
        private String WARRANTY_PDF_FILE_NAME;
        private String WARRANTY_PDF_MD5;
        private String ORDER_FILE_NAME;

        private String ORDER_MD5;
        private String ORDER_PDF_FILE_NAME;
        private String ORDER_PDF_MD5;
        private String QUALFICATION_FILE_NAME;
        private String QUALFICATION_FILE_MD5;

        private String BUSINESS_LICENSE_FILE_NAME;
        private String BUSINESS_LICENSE_MD5;

        private String OTHER_FILE_NAME;
        private String OTHER_FILE_MD5;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
                    sb.append("<GUARANTEE_ATTACHMENT")
                    .append(" WARRANTY_FILE_NAME=" + trim(WARRANTY_FILE_NAME))
                    .append(" WARRANTY_MD5=" + trim(WARRANTY_MD5))
                    .append(" WARRANTY_PDF_FILE_NAME=" + trim(WARRANTY_PDF_FILE_NAME))
                    .append(" WARRANTY_PDF_MD5=" + trim(WARRANTY_PDF_MD5))
                    .append(" ORDER_FILE_NAME=" + trim(ORDER_FILE_NAME))

                    .append(" ORDER_MD5=" + trim(ORDER_MD5))
                    .append(" ORDER_PDF_FILE_NAME=" + trim(ORDER_PDF_FILE_NAME))
                    .append(" ORDER_PDF_MD5=" + trim(ORDER_PDF_MD5))
                    .append(" QUALFICATION_FILE_NAME=" + trim(QUALFICATION_FILE_NAME))
                    .append(" QUALFICATION_FILE_MD5=" + trim(QUALFICATION_FILE_MD5))

                    .append(" BUSINESS_LICENSE_FILE_NAME=" + trim(BUSINESS_LICENSE_FILE_NAME))
                    .append(" BUSINESS_LICENSE_MD5=" + trim(BUSINESS_LICENSE_MD5));

                    // 厦门字段为OTHER_FILE_NAME、OTHER_FILE_MD5，福建省内其他地区标准为OTHER_FIE_NAME、OTHER_FIE_MD5
                    if(CreateGuaranteeUtil.isXiaMen(centerNoEnum)){
                        sb.append(" OTHER_FILE_NAME=" + trim(OTHER_FILE_NAME));
                        sb.append(" OTHER_FILE_MD5=" + trim(OTHER_FILE_MD5));
                    } else {
                        sb.append(" OTHER_FIE_NAME=" + trim(OTHER_FILE_NAME));
                        sb.append(" OTHER_FIE_MD5=" + trim(OTHER_FILE_MD5));
                    }

                    sb.append("></GUARANTEE_ATTACHMENT>");
            return sb.toString();
        }
    }

    /**
     * 发票信息(INVOICE_INFO)
     */
    @Getter
    @Setter
    @Builder
    public static class InvoiceInfo implements Serializable {
        private String INVOICE_TITLE;
        private String INVOICE_NO;
        private String CUSTOMER_NAME;
        private String CUSTOMER_CREDIT_CODE;
        private String CUSTOMER_BANK_CODE;
        private String CUSTOMER_OPNE_BANK;
        private String CUSTOMER_ADDRESS;
        private String CUSTOMER_PHONE;

        private String PRODUCT_NAME;
        private String AMOUNT;
        private String AMOUNT_OF_CHINAESE;
        private String OPEN_TIME;
        private String SELLER_NAME;
        private String SELLER_CREDIT_CODE;

        private String SELLER_BANK_CODE;
        private String SELLER_OPEN_BANK;
        private String SELLER_ADDRESS;
        private String SELLER_PHONE;

        private String HANDLER;
        private String INVOICE_REMARK;

        @Override
        public String toString() {
            return new StringBuilder("<INVOICE_INFO")
                    .append(" INVOICE_TITLE=" + trim(INVOICE_TITLE))
                    .append(" INVOICE_NO=" + trim(INVOICE_NO))
                    .append(" CUSTOMER_NAME=" + trim(CUSTOMER_NAME))
                    .append(" CUSTOMER_CREDIT_CODE=" + trim(CUSTOMER_CREDIT_CODE))
                    .append(" CUSTOMER_BANK_CODE=" + trim(CUSTOMER_BANK_CODE))
                    .append(" CUSTOMER_OPNE_BANK=" + trim(CUSTOMER_OPNE_BANK))
                    .append(" CUSTOMER_ADDRESS=" + trim(CUSTOMER_ADDRESS))
                    .append(" CUSTOMER_PHONE=" + trim(CUSTOMER_PHONE))

                    .append(" PRODUCT_NAME=" + trim(PRODUCT_NAME))
                    .append(" AMOUNT=" + trim(AMOUNT))
                    .append(" AMOUNT_OF_CHINAESE=" + trim(AMOUNT_OF_CHINAESE))
                    .append(" OPEN_TIME=" + trim(OPEN_TIME))
                    .append(" SELLER_NAME=" + trim(SELLER_NAME))
                    .append(" SELLER_CREDIT_CODE=" + trim(SELLER_CREDIT_CODE))

                    .append(" SELLER_BANK_CODE=" + trim(SELLER_BANK_CODE))
                    .append(" SELLER_OPEN_BANK=" + trim(SELLER_OPEN_BANK))
                    .append(" SELLER_ADDRESS=" + trim(SELLER_ADDRESS))
                    .append(" SELLER_PHONE=" + trim(SELLER_PHONE))
                    .append(" HANDLER=" + trim(HANDLER))
                    .append(" INVOICE_REMARK=" + trim(INVOICE_REMARK))
                    .append("></INVOICE_INFO>")
                    .toString();

        }

    }


    /**
     * xml属性值 前后去空格后加双引号
     */
    private static String trim(String val) {
        String tmpVal = (val == null) ? "" : val.trim();
        return "\"" + tmpVal + "\"";
    }

}
